#ifndef __MY_BUFFER_H__
#define __MY_BUFFER_H__

#include <iostream>
#include <vector>
#include <cassert>

namespace LzcLog
{
    #define DEFAULT_BUFFER_SIZE (1 * 1024 * 1024)
    #define THRESHOLD_BUFFER_SIZE (8 * 1024 * 1024)
    #define GROWTH_BUFFER_SIZE (1 * 1024 * 1024)
    class Buffer
    {
    public:
        Buffer() 
            : _buffer(DEFAULT_BUFFER_SIZE)
            , _reader_index(0)
            , _writer_index(0)
        {}
        void Push(const char* data, size_t len)
        {
            if (data == nullptr || len == 0) // 空指针/空长度直接返回
                return;
            EnsureEnough(len); // 确保有足够的空间
            std::copy(data, data + len, _buffer.begin() + _writer_index); // 拷贝字符串
            MoveWriterIdx(len); // 移动写指针
        }
        const char* Begin() { return &_buffer[_reader_index]; }
        size_t ReadAbleSize() { 
            // 当前实现的缓冲区，是双缓冲区，并不是循环缓冲区，只会向后写，然后交换
            return _writer_index - _reader_index; 
        }
        size_t WriteAbleSize() {
            // 对于扩容，总是可写；仅仅为固定大小的缓冲区提供
            return _buffer.size() - _writer_index;
        }
        void MoveReaderIdx(size_t len) {
            assert(len <= ReadAbleSize());
            _reader_index += len;
        }
        void Reset() {
            _writer_index = 0;
            _reader_index = 0;
        }
        void Swap(Buffer& buffer) {
            std::swap(_buffer, buffer._buffer); // 是交换vector内部的指针
            std::swap(_reader_index, buffer._reader_index);
            std::swap(_writer_index, buffer._writer_index);
        }
        bool Empty() { return _reader_index == _writer_index; }
    private:
        void EnsureEnough(size_t len)
        {
            if(_buffer.size() >= _writer_index + len) return;
            size_t new_size = _buffer.size();
            while(new_size < _writer_index + len)
            {
                if(new_size < THRESHOLD_BUFFER_SIZE) // 小于阈值，翻倍增长
                    new_size *= 2;
                else
                    new_size += GROWTH_BUFFER_SIZE; // 否则，线性增长
            }
            _buffer.resize(new_size);
        }
        void MoveWriterIdx(size_t len)
        {
            assert(len <= WriteAbleSize());
            _writer_index += len;
        }
    private:
        std::vector<char> _buffer;
        size_t _reader_index; // 当前可读数据的指针，本质是下标
        size_t _writer_index; // 当前可写数据的指针，本质是下标
    };
}

#endif